from fastapi import FastAPI
from contextlib import asynccontextmanager
from config import settings
from core import Exception, Events, Router, Middleware
from fastapi.templating import Jinja2Templates
from tortoise.exceptions import OperationalError, DoesNotExist, IntegrityError, ValidationError
from fastapi.openapi.docs import (get_redoc_html, get_swagger_ui_html, get_swagger_ui_oauth2_redirect_html)
from fastapi.openapi.utils import get_openapi
from fastapi.staticfiles import StaticFiles

# 定义启动和关闭逻辑
@asynccontextmanager
async def lifespan(app: FastAPI):
    await Events.startup(app)
    yield
    print("Shutting down...")
    await Events.shutdown(app)

main_app = FastAPI(
    title=settings.APP_TITLE,
    description=settings.APP_DESCRIPTION,
    version=settings.APP_VERSION,
    debug=settings.APP_DEBUG,
    docs_url=None,
    redoc_url=None,
    swagger_ui_oauth2_redirect_url=settings.SWAGGER_UI_OAUTH2_REDIRECT_URL,
    lifespan=lifespan
)

# custom_openapi
def custom_openapi():
    if main_app.openapi_schema:
        return main_app.openapi_schema
    openapi_schema = get_openapi(
        description=main_app.description,
        version=main_app.version,
        title=main_app.title,
        routes=main_app.routes,
    )
    openapi_schema["info"]["x-logo"] = {
        "url": "/logo-teal.png"
    }
    main_app.openapi_schema = openapi_schema
    return main_app.openapi_schema


main_app.openapi = custom_openapi


# custom_swagger_ui_html
@main_app.get("/docs", include_in_schema=False)
async def custom_swagger_ui_html():
    return get_swagger_ui_html(
        openapi_url = main_app.openapi_url,
        title = main_app.title + " - 接口文档",
        oauth2_redirect_url = main_app.swagger_ui_oauth2_redirect_url,
        swagger_js_url="/static/swagger-ui/swagger-ui-bundle.js",
        swagger_css_url="/static/swagger-ui/swagger-ui.css",
    )

# swagger_ui_oauth2_redirect_url
@main_app.get(main_app.swagger_ui_oauth2_redirect_url, include_in_schema=False)
async def swagger_ui_redirect():
    return get_swagger_ui_oauth2_redirect_html()

# redoc
@main_app.get("/redoc", include_in_schema=False)
async def redoc_html():
    return get_redoc_html(
        openapi_url=main_app.openapi_url,
        title=main_app.title + " - ReDoc",
        redoc_js_url="/static/js/redoc.standalone.js",
    )

# 路由
main_app.include_router(Router.router)
# 静态资源目录
main_app.mount('/static', StaticFiles(directory=settings.STATIC_DIR), name="static")
main_app.state.views = Jinja2Templates(directory=settings.TEMPLATE_DIR)

@main_app.get("/")
async def read_root():
    return {"Hello": "World"}

app = main_app